#ifndef HTTP_PROTOCOL_PARSER_H_
#define HTTP_PROTOCOL_PARSER_H_

#include "http_protocol_msg.h"

#include <cstdint>
#include <map>
#include <vector>

class HttpRequestProtocolParser
{
public:
    enum ParserHttpStatus
    {
        INI,
        NEED_DATA,
        FINISH,
        BAD,
    };
    enum HttpProtocolStatus
    {
        PARSER_INIT,
        PARSER_HEADER_LINE,
        PARSER_HEADER_LINE_FINISH,
        PARSER_HEADER_SIGN,
        PARSER_HEADER_SIGN_FINISH,
        PARSER_BODY,
        PARSER_BODY_FINISH,
        PARSER_BAD,
    };

public:
    HttpRequestProtocolParser();
    void          Clear();
    int           ParseHttpRequestProtocol(const uint8_t * data, int data_size, int & use_length);
    HttpRequest * Request();

private:
    int         m_http_parser_status;
    HttpRequest m_http_request;
};

class HttpResponseProtocolParser
{
public:
    enum ParserHttpStatus
    {
        INIT,
        NEED_DATA,
        FINISH,
        BAD
    };
    enum HttpProtocolStatus
    {
        PARSER_INIT,
        PARSER_HEADER_LINE,
        PARSER_HEADER_LINE_FINISH,
        PARSER_HEADER_SIGN,
        PARSER_HEADER_SIGN_FINISH,
        PARSER_BODY,
        PARSER_BODY_FINISH,
        PARSER_BAD
    };

public:
    HttpResponseProtocolParser();
    void           Clear();
    int            ParseHttpResponseProtocol(const uint8_t * data, int data_length, int & use_length);
    HttpResponse * Response();
    int            ParserStatus() const;
private:
    int          m_http_parser_status;
    HttpResponse m_http_response;
};

class HttpProtocolUtil
{
public:
    static int ParseHttpProtocolLine(const uint8_t * data, int data_length, int & length, HttpRequest * http_request);
    static int ParseHttpProtocolLine(const uint8_t * data, int data_length, int & lengthm, HttpResponse * http_response);
    static int ParseHttpProtocolSign(const uint8_t * data, int data_length, int & length,
                                     std::map<std::string, std::string> & sign_map);
    static int ParseHttpProtocolBody(const uint8_t * data, int data_length, int & length, int body_length,
                                     std::vector<uint8_t> & body);
    static int ParseHttpProtocolChunk(const uint8_t * data, int data_length, int & length, std::vector<uint8_t> & body);

    static int HexToDec(const char * data, int length);
};

#endif //
